package ch.zhaw.cctd.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.util.List;
import java.util.Map;

import javax.swing.JPanel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.zhaw.cctd.domain.DomainFacade;
import ch.zhaw.cctd.domain.prototype.MapElementPrototype;
import ch.zhaw.cctd.domain.prototype.MapPrototype;
import ch.zhaw.cctd.domain.prototype.PrototypeList;

/**
 * Ein JPanel, welches die LobbyMap darstellt. Darauf ist zu sehen, welcher
 * Spieler im Spiel wo platziert sein wird.
 * 
 * @author nathanaelkoch
 * 
 */
public class LobbyMap extends JPanel {

	/**
	 * Logger
	 */
	private static final Logger logger = LoggerFactory.getLogger(LobbyMap.class);

	private static final long serialVersionUID = 133606106903613391L;
	private Map<Integer, String> playerList;
	private int userId;
	private Dimension relativeSize;
	private int side;
	PrototypeList plist;
	MapPrototype mp;
	List<MapElementPrototype> mapElementList;

	public LobbyMap(Map<Integer, String> playerList, int userId) {
		super();
		this.playerList = playerList;
		this.userId = userId;
		plist = DomainFacade.getPrototypeList();
		mp = plist.getPrototypes(MapPrototype.class).get(0);
		mapElementList = mp.getMapElementPrototypes();
	}

	private void setRelativeSize(Dimension relativeSize) {
		this.relativeSize = relativeSize;
	}

	private Dimension getRelativeSize() {
		return relativeSize;
	}

	private double calcX(double relX) {
		double out = relX * scaleXFactor();
		return out;
	}

	private double calcY(double relY) {
		double out = relY * scaleYFactor();
		return out;
	}

	private double scaleXFactor() {
		double out = this.side / getRelativeSize().getWidth();
		return out;
	}

	private double scaleYFactor() {

		double out = this.side / getRelativeSize().getHeight();
		return out;
	}

	public void paint(Graphics g) {
		// this.width = this.getHeight()-3;
		// this.height = this.getHeight()-3;
		// Create the Map

		logger.debug("Size: " + mp.getSize());
		setRelativeSize(new Dimension(mp.getSize(), mp.getSize()));
		// int size = mp.getSize();
		// List<SpawnPointPrototype> spawnPointList =
		// mp.getSpawnPointPrototypes();

		logger.debug("mapElementList size: " + mapElementList.size());
		g.setColor(Color.white);
		this.side = Math.min(this.getWidth(), this.getHeight());
		int xoffset = Math.max(0, this.getWidth() - this.getHeight());
		g.fillRect(xoffset, 0, side, side);

		for (MapElementPrototype mep : mapElementList) {
			logger.debug("found element");
			if (mep.isConstructionZone()) {
				logger.debug("its a constructionzone");
				int ownerId = mep.getPlayerid();
				if (ownerId == userId) {
					g.setColor(new Color(200, 255, 200));
				} else if (playerList.get(ownerId) != null) {
					g.setColor(Color.GRAY);
				} else {
					g.setColor(Color.LIGHT_GRAY);
				}
				// Point point = new Point(mep.getXX(), mep.getXY());
				// Dimension dimension = new Dimension(mep.getYX()-mep.getXX(),
				// mep.getYY()-mep.getXY());
				logger.trace("Print something at {}:{}", (int) calcX(mep.getXX()) + xoffset, (int) calcY(mep.getXY()));
				g.fillRect(
						(int) Math.ceil(calcX(mep.getXX()) + xoffset), 
						(int) Math.ceil(calcY(mep.getXY())), 
						(int) Math.ceil(calcX(mep.getYX() - mep.getXX())),
						(int) Math.ceil(calcY(mep.getYY() - mep.getXY()))
				);
				if (playerList.get(ownerId) != null) {
					g.setColor(Color.BLACK);
					Font tmp = g.getFont();
					double fontSizefactor = 0.6;
					int fontSize = (int) (calcY(mep.getYY() - mep.getXY()) / 2 * fontSizefactor);
					g.setFont(new Font(null, Font.BOLD, fontSize));
					g.drawString(String.valueOf(ownerId), 
							(int) (calcX(mep.getXX()) + calcX(mep.getYX() - mep.getXX()) / 2 + xoffset - fontSize/3),
							(int) (calcY(mep.getXY()) + calcY(mep.getYY() - mep.getXY()) / 2 + fontSize / 3)
					);
					g.setFont(tmp);
				}
			} else if (mep.isBackground()) {
				logger.trace("got background. printing it white");
				g.setColor(Color.white);
				g.fillRect((int) Math.ceil(calcX(mep.getXX()) + xoffset), (int) Math.ceil(calcY(mep.getXY())), (int) Math.ceil(calcX(mep.getYX() - mep.getXX())),
						(int) Math.ceil(calcY(mep.getYY() - mep.getXY())));
			} else {
				logger.trace("Got something else, printing it black");
				g.setColor(Color.black);
				g.fillRect((int) Math.ceil(calcX(mep.getXX()) + xoffset), (int) Math.ceil(calcY(mep.getXY())), (int) Math.ceil(calcX(mep.getYX() - mep.getXX())),
						(int)Math.ceil( calcY(mep.getYY() - mep.getXY())));
			}
		}
	}

	public void setPlayerList(Map<Integer, String> playerList) {
		this.playerList = playerList;
	}
}
